import Cat2DocImg from "./elements/img";
import Cat2DocTable from "./elements/table";
import Cat2DocResize from "./utils/resize";
import Cat2DocPre from "./elements/pre";
import {setTitleNumber} from "./utils/title";
import Cat2DocText from "./elements/text";
import {createId, hasC2dElementId} from "./utils/id";
/** 文档内容 */
class Cat2DocContent {
    #content = null;
    #observer = null;
    #rowMouseEnter = this.#handleRowMouseEnter.bind(this);
    #rowMouseMove = this.#handleRowMouseMove.bind(this);
    #rowMouseLeave = this.#handleRowMouseLeave.bind(this);
    #resize = null;
    constructor(parentElement, options) {
        this.#content = createContent(parentElement, options);
        this.#resize = new Cat2DocResize(this.#content);
        this.#init(options);
    }

    #init(options) {
        // 创建一个观察器实例并传入回调函数
        this.#observer = new MutationObserver((mutationsList, observer) => {
            const opts = {
            ...options,
            ...{
                drag: this.#resize
            }}
            for(let mutation of mutationsList) {
                if (mutation.type === 'childList') {
                    // 为新增的元素添加属性和事件
                    let addedNode = [];
                    mutation.addedNodes.forEach(d=>{
                        // 如果是改变尺寸组件，则不处理
                        if(this.#resize && this.#resize.isType(d)) return;
                        // // 如果新增的元素是纯文本，将其改为p元素
                        if (d.nodeType === Node.TEXT_NODE){
                            if(d.textContent==='\n') {
                                d.remove();
                                return;
                            }
                            let newD = createPElement(d.textContent);
                            this.#content.insertBefore(newD,d);
                            d.remove();
                            setSelect(newD);
                            return;
                        } else if(d.tagName !== 'P') { // 为所有不是P的元素添加一个父级
                            let newD = createPElement();
                            newD.appendChild(d.cloneNode(true));
                            this.#content.insertBefore(newD,d);
                            d.remove();
                            return;
                        }
                        // 如果段落没有id或者不是c2d创建的元素id，则新建id
                        if(hasC2dElementId(d)===false) {
                            d.setAttribute('id', createId());
                        }

                        // 添加内容的事件
                        d.addEventListener('mouseenter', this.#rowMouseEnter);
                        d.addEventListener('mousemove', this.#rowMouseMove);
                        d.addEventListener('mouseleave', this.#rowMouseLeave);
                        if (Cat2DocImg.isType(d)) {
                            // 如果是图片元素，初始化元素的相关数据或操作
                            Cat2DocImg.initElement(d, opts);
                        } else if (Cat2DocTable.isType(d)) {
                            // 如果是表格元素，初始化元素的相关数据或操作
                            Cat2DocTable.initElement(d, opts);
                        } else if(Cat2DocPre.isType(d)) {
                            Cat2DocPre.initElement(d, opts);
                        } else if(Cat2DocText.isType(d)) {
                            Cat2DocText.initElement(d, opts);
                        }
                        addedNode.push(d);
                    });
                    if(mutation.addedNodes.length>0) {
                        let addedNodesEvent = new CustomEvent("added-nodes", {
                            detail: {
                                target: addedNode
                            },
                        });
                        this.#content.dispatchEvent(addedNodesEvent);
                    }
                    // 为删除的元素移出事件
                    mutation.removedNodes.forEach(d=>{
                        // 如果是改变尺寸组件，则不处理
                        if(this.#resize && this.#resize.isType(d)) return;
                        // 移除内容的事件
                        d.removeEventListener('mouseenter', this.#rowMouseEnter);
                        d.removeEventListener('mousemove', this.#rowMouseMove);
                        d.removeEventListener('mouseleave', this.#rowMouseLeave);
                        // 如果是图片元素，释放元素的相关数据或操作
                        Cat2DocImg.isType(d) && Cat2DocImg.destoryElement(d, opts);
                        // 如果是表格元素，释放元素的相关数据或操作
                        Cat2DocTable.isType(d) && Cat2DocTable.destoryElement(d, opts);
                        // 如果是代码块元素，释放元素的相关数据或操作
                        Cat2DocPre.isType(d) && Cat2DocPre.destoryElement(d, opts);
                    });
                    if(mutation.removedNodes.length>0) {
                        let removedNodesEvent = new CustomEvent("removed-nodes", {
                            detail: {
                                target: mutation.removedNodes
                            },
                        });
                        this.#content.dispatchEvent(removedNodesEvent);
                    }
                    setTitleNumber(this.#content, 0,0,this.#content.childNodes.length-1,null);
                } else if (mutation.type === 'attributes') {}
            }
        });
        this.#observer.observe(this.#content, { attributes: false, childList: true, subtree: false });
    }
    /** 释放 */
    destory() {
        if(this.#observer) {
            this.#observer.disconnect();
        }
    }
    reset() {
        this.#content.innerHTML = '';
    }
    /** 加载内容 */
    loadContent(text) {
        // 加载文档时先释放改变尺寸组件
        if(this.#resize) {
            this.#resize.destory();
            this.#resize = null;
        }
        // 加载文档后重新创建改变尺寸组件
        this.#content.innerHTML = text;
        this.#resize = new Cat2DocResize(this.#content);
    }
    /** 获取内容的element */
    get $el() {
        return this.#content;
    }
    /** dom的x坐标 */
    get left() {
        return this.#content.offsetLeft;
    }
    /** dom的y坐标 */
    get top() {
        return this.#content.offsetTop;
    }
    /** 获取行元素 */
    getRowElement(id) {
        return document.getElementById(id);
    }
    /** 获取焦点 */
    focus() {
        this.#content.focus();
    }

    /** 鼠标进入doc文档每行时的事件 */
    #handleRowMouseEnter(event) {
        let rowMouseEnterEvent = new CustomEvent("row-mouse-enter", {
            detail: {
                target: event.target
            },
        });
        this.#content.dispatchEvent(rowMouseEnterEvent);
    }
    /** 鼠标离开doc文档每行时的事件 */
    #handleRowMouseLeave(event) {
        let rowMouseLeaveEvent = new CustomEvent("row-mouse-leave", {
            detail: {
                target: event.target
            },
        });
        this.#content.dispatchEvent(rowMouseLeaveEvent);
    }
    /** 鼠标移动在doc文档每行时的事件 */
    #handleRowMouseMove(event) {
        let rowMouseMoveEvent = new CustomEvent("row-mouse-move", {
            detail: {
                target: event.target
            },
        });
        this.#content.dispatchEvent(rowMouseMoveEvent);
    }
}

/** 创建文档区域div */
function createContent(parentElement, options) {
    let opts = {
        ...{
            edit: true
        },
        ...options
    }
    let div = document.createElement('div');
    div.setAttribute("contenteditable", opts.edit);
    div.className = 'c2d-doc';
    div.style.zIndex = '1';
    div.style.overflowX = 'hidden';
    div.style.overflowY = 'auto';
    div.style.position = 'relative';
    parentElement.appendChild(div);
    return div;
}
/** 创建p元素 */
function createPElement(text) {
    let p = document.createElement('p');
    if(text) p.innerText = text;
    return p;
}
/** 设置光标位置 */
function setSelect(ele) {
    let range = document.createRange();
    range.selectNodeContents(ele);
    let selection = window.getSelection();
    selection.removeAllRanges(); // 清除之前的选中范围
    selection.addRange(range); // 添加新的选中范围
}

export default Cat2DocContent;
